package com.kehutong.charge.service.impl;

import com.kehutong.charge.dto.ChargeStatistDTO;
import com.kehutong.charge.entity.*;
import com.kehutong.charge.service.ChargeHouseService;
import com.kehutong.charge.util.CommonClient;
import com.kehutong.charge.util.enums.ResidentsTypeEnum;
import com.kehutong.common.DeptService;
import com.kehutong.common.DoveClient;
import com.kehutong.common.dto.DeptDTO;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.util.Token;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: kht
 * @description: ChargeHouseServiceImpl
 * @author: joneron
 * @create: 2021/6/23
 **/
@WebService("/charge/house/config/service")
public class ChargeHouseServiceImpl implements ChargeHouseService {

    private static final Logger logger = LoggerFactory.getLogger(ChargeHouseServiceImpl.class);

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    CommonClient commonClient;

    @Inject
    DeptService deptService;

    @Inject
    private DoveClient doveClient;

    @Override
    public Page<ChargeHouseConfig> findPage(JSONObject jsonObject) {
        FindPage<ChargeHouseConfig> find = jdbcSession.findPage(ChargeHouseConfig.class)
                .eq("deleted", false)
                .eq(jsonObject,"communityNo")
                .eq(jsonObject,"configStatus")
                .like(jsonObject,"chargeName")
                .eq(jsonObject,"status")
                .order("createTime", "desc");

        String serviceNo = jsonObject.getString("searchName");
        if(Objects.nonEmpty(serviceNo)){
            find.markBegin();
            find.like("communityName",serviceNo).or();
            find.like("buildName",serviceNo).or();
            find.like("mergeName",serviceNo).or();
            find.markEnd();
        }
        find.page(jsonObject);
        Page<ChargeHouseConfig>page=find.exe();
        page.getList().forEach(item->{
            List<MeterManage>meterManageList=jdbcSession.findArray(MeterManage.class)
                    .eq("deleted", false)
                    .eq( "communityNo",item.getCommunityNo())
                    .eq("houseNo",item.getHouseNo())
                    .eq("status",true)
                    .exe();  //仪表
            item.setMeterNumber(meterManageList.size());
            List<ChargeHouseSet>chargeHouseSetList=jdbcSession.findArray(ChargeHouseSet.class)
                    .eq("deleted",false)
                    .eq( "communityNo",item.getCommunityNo())
                    .eq("houseNo",item.getHouseNo())
                    .exe();
            if(chargeHouseSetList.size()>0){
                item.setConfigNumber(chargeHouseSetList.size());
            }
        });
        return page;
    }

    @Override
    public List<ChargeHouseConfig> findList(JSONObject jsonObject) {
        return jdbcSession.findArray(ChargeHouseConfig.class)
                .eq("deleted", false)
                .exe();
    }

    @Override
    public Object save(ChargeHouseConfig chargeHouseConfig) {
        chargeHouseConfig.setConfigStatus(false);
        jdbcSession.insert(chargeHouseConfig);
        return 1;
    }

    @Override
    public Object update(ChargeHouseConfig chargeHouseConfig) {

        chargeHouseConfig.setConfigStatus(true);
        return jdbcSession.updateById(chargeHouseConfig);
    }

    @Override
    public Object deleteById(String id) {
        ChargeHouseConfig result = Pool.get(ChargeHouseConfig.class, id);
        if (result != null) {
            result.setDeleted(true);
            jdbcSession.updateById(result);
        }
        return 1;
    }

    @Override
    public Object updateHouseSet(ChargeHouseConfig entity, JSONObject jsonObject) {

        JSONArray houseSetList = jsonObject.getJSONArray("houseList");

        //先查询已配置的信息，再删除已配置信息
        List<ChargeHouseSet> pps = jdbcSession.findArray(ChargeHouseSet.class).eq(
                "chargeHouseNo",entity.getId()).exe();
        for (int i = 0; i < pps.size(); i++) {
            jdbcSession.deleteById(ChargeHouseSet.class,pps.get(i).getId());
        }

        for (int i = 0; i < houseSetList.size(); i ++) {
            JSONObject json = houseSetList.getJSONObject(i);
            ChargeHouseSet set = Pool.newInstance(ChargeHouseSet.class);
            String feeTypeNo = json.getString("feeTypeNo");
            set.setFeeTypeNo(feeTypeNo);
            set.setProjectFeeNo(json.getString("projectFeeNo"));
            set.setCommunityNo(entity.getCommunityNo());
            set.setCommunityName(json.getString("communityName"));
            set.setHouseNo(entity.getHouseNo());
            set.setChargeHouseNo(entity.getId());
            set.setCreateName(entity.getCreateName());
            set.setUpdateName(entity.getUpdateName());
            jdbcSession.insert(set);
        }

        entity.setConfigStatus(true);
        return jdbcSession.updateById(entity);
    }

    @Override
    public Object saveSet(ChargeHouseSet chargeHouseSet) {
        ChargeHouseSet temp = jdbcSession.findById(chargeHouseSet.getClass(),chargeHouseSet.getId());
        int row;
        if(temp != null){
            List<ChargeHouseSet> chargeHouseSetList = jdbcSession.findArray(ChargeHouseSet.class)
                    .eq("chargeHouseNo",chargeHouseSet.getChargeHouseNo())
                    .eq("projectFeeNo",chargeHouseSet.getProjectFeeNo())
                    .eq("feeTypeNo",chargeHouseSet.getFeeTypeNo())
                    .noEq("id",chargeHouseSet.getId()).exe();
            if(chargeHouseSetList.size()>0){
                return Result.error(2021, "配置重复项！");
            }
            row = jdbcSession.updateById(chargeHouseSet);
        }else{
            List<ChargeHouseSet> chargeHouseSetList = jdbcSession.findArray(ChargeHouseSet.class).eq("chargeHouseNo",chargeHouseSet.getChargeHouseNo())
                    .eq("projectFeeNo",chargeHouseSet.getProjectFeeNo()).eq("feeTypeNo",chargeHouseSet.getFeeTypeNo()).exe();
            if(chargeHouseSetList.size()>0){
                return Result.error(2021, "配置重复项！");
            }
            row= jdbcSession.insert(chargeHouseSet);
        }

        List<ChargeHouseSet> chargeHouseSetList = jdbcSession.findArray(ChargeHouseSet.class).eq("houseNo", chargeHouseSet.getHouseNo())
                .eq("communityNo", chargeHouseSet.getCommunityNo()).eq("deleted", false)
                .exe();
        ChargeHouseSet owner = null;
        ChargeHouseSet other = null;
        for (ChargeHouseSet each : chargeHouseSetList) {
            if (each.getReType() == ResidentsTypeEnum.OWNER) {
                owner = each;
            }
            else {
                other = each;
            }
        }

        ChargeHouseConfig houseConfig = jdbcSession.findOne(ChargeHouseConfig.class)
                .eq("deleted", false)
                .eq("houseNo", chargeHouseSet.getHouseNo())
                .exe();
        if (houseConfig != null) {
            if (owner != null) {
                houseConfig.setChargeName(owner.getChargeName());
                houseConfig.setOwnerNo(owner.getChargeId());
                houseConfig.setReType(owner.getReType());
            } else if (other != null){
                houseConfig.setChargeName(other.getChargeName());
                houseConfig.setOwnerNo(other.getChargeId());
                houseConfig.setReType(other.getReType());
            }
            jdbcSession.updateById(houseConfig);
        }
        return row;
    }

    @Override
    public Object findFeeDetail(JSONObject jsonObject) {

        String ids = jsonObject.getString("id");
        if(StringUtil.isNotEmpty(ids)){
            
            List<ChargeHouseSet> config = jdbcSession.findArray(ChargeHouseSet.class)
                    .eq("deleted", false)
                    .eq("chargeHouseNo",ids)
                    .exe();

            List<ChargeProjectConfig> array = new ArrayList();
            
            for (int i = 0; i < config.size(); i++) {

                ChargeProjectConfig pconfig = jdbcSession.findById(ChargeProjectConfig.class,config.get(i).getProjectFeeNo());

                array.add(pconfig);
            }
            return array;
        }
        return null;
    }

    @Override
    public List<ChargeHouseSet> findSetList(JSONObject jsonObject) {
        List<ChargeHouseSet>chargeHouseSetList=jdbcSession.findArray(ChargeHouseSet.class)
                .eq("deleted", false)
                .eq(jsonObject,"houseNo")
                .exe();
        chargeHouseSetList.forEach(item->{
            ChargeProjectConfig chargeProjectConfig=jdbcSession.findById(ChargeProjectConfig.class,item.getProjectFeeNo());
            item.setChargeProjectConfig(chargeProjectConfig);
            //阶梯价
            List<ChargeLadderConfig> configList = jdbcSession.findArray(ChargeLadderConfig.class)
                    .eq("chargeProjectNo",chargeProjectConfig.getId())
                    .order("usageStart","asc").exe();
            chargeProjectConfig.setLadderList(configList);
        });
        return chargeHouseSetList;

    }


    @Override
    public Object listByMultiple(JSONObject jsonObject) {
        JSONArray unitNameSet = jsonObject.getJSONArray("unitNameSet");

        FindArray<ChargeHouseConfig> houseFind = jdbcSession.findArray(ChargeHouseConfig.class);
        houseFind.eq("deleted",false);
        houseFind.in("communityName",jsonObject.getJSONArray("communitySet"));
        houseFind.in("buildName",jsonObject.getJSONArray("buildSet"));
        houseFind.in("mergeName",jsonObject.getJSONArray("houseNoSet"));
        if(!Objects.isEmpty(unitNameSet)){
            houseFind.in("unitName",unitNameSet);
        }
        return houseFind.exe();
    }

    @Override
    public Object setStatus(ChargeHouseConfig entity) {
        return jdbcSession.updateById(entity);
    }

    @Override
    public Object deleteChargeHouseSet(ChargeHouseSet chargeHouseSet) {
        return jdbcSession.deleteById(chargeHouseSet);
    }



    @Override
    public Object synHouseData(JSONObject jsonObject,Token token) throws Exception {

        List<ChargeHouseConfig> list = jdbcSession.findArray(ChargeHouseConfig.class)
                .eq("deleted",false)
                .eq(jsonObject,"communityNo")
                .exe();
        List<String> houseIds = list.stream().map(ChargeHouseConfig::getHouseNo).collect(Collectors.toList());

        List<String> departList = token.getDepartments();
        if(!Objects.isEmpty(departList)){

            DeptDTO deptDTO = deptService.getDept(departList.get(0));

            Map<String,JSONObject> communityMap = commonClient.getHouseMap(jsonObject.getString("communityNo"));

            communityMap.forEach((k,v)->{
                //先判断房屋是否存在
                if(!houseIds.contains(v.getString("id"))){
                    insetData(v,deptDTO);
                }
            });
            //缴费模块有数据，资产模块已删除，则删除缴费模块数据
            list.stream().forEach(item->{
                if(!communityMap.containsKey(item.getHouseNo())){
                    jdbcSession.deleteById(ChargeHouseConfig.class, item.getId());
                }
            });
        }
        return Result.success();
    }

    /**
     * 添加房屋绑定设置
     */
    private void insetData(JSONObject obj,DeptDTO deptDTO){

        ChargeHouseConfig config = Pool.newInstance(ChargeHouseConfig.class);
        config.setCommunityNo(obj.getString("communityNo"));
        config.setCommunityName(obj.getString("communityName"));
        config.setHouseNo(obj.getString("id"));
        config.setBuildNo(obj.getString("buildNo"));
        config.setBuildName(obj.getString("buildName"));
        config.setUnitName(obj.getString("unitName"));
        config.setMergeName(obj.getString("mergeName"));
        config.setChargeName(obj.getString("ownerName"));
        config.setChargeArea(obj.getString("payArea"));
        config.setOwnerNo(obj.getString("ownerNo"));
        config.setHouseName(obj.getString("name"));
        config.setReType(ResidentsTypeEnum.OWNER);
        config.setConfigStatus(false);
        config.setDepartmentNo(deptDTO.getDepartmentNo());
        config.setDepartmentNos(deptDTO.getDepartmentNos());
        config.setDepartmentName(deptDTO.getDepartmentName());

        jdbcSession.insert(config);
    }

    @Override
    public List<ChargeStatistDTO> findStatistPage(Token token, JSONObject jsonObject) throws Exception {

        List<ChargeStatistDTO> statList = new ArrayList<>();

        Map<String,JSONObject> communityMap = commonClient.getCommunityMap();

        String communityNo = jsonObject.getString("communityNo");

        JSONObject community = communityMap.get(communityNo);
        if(Objects.nonNull(community)){
            communityMap.clear();
            communityMap.put("communityNo",community);
        }

        //同步数据
        //synHouseData(jsonObject,token);

        communityMap.forEach((k,v)-> {

            try {
                jsonObject.put("communityNo",k);
                synHouseData(jsonObject,token);
            } catch (Exception e) {
            }

            String viewName = v.getString("name");
            List<ChargeHouseConfig> meterType = jdbcSession.findArray(ChargeHouseConfig.class)
                    .eq("deleted", false)
                    .eq("configStatus", true)
                    .eq( "communityNo",k)
                    .exe();

            List<ChargeHouseConfig> meterTypeNO = jdbcSession.findArray(ChargeHouseConfig.class)
                    .eq("deleted", false)
                    .eq("configStatus", false)
                    .eq( "communityNo",k)
                    .exe();

            ChargeStatistDTO configStatistDTO = new ChargeStatistDTO();
            configStatistDTO.setCommunityName(viewName);
            configStatistDTO.setConfigNumberNO(meterTypeNO.size());
            configStatistDTO.setConfigNumber(meterType.size());
            configStatistDTO.setCommunityNo(k);

            statList.add(configStatistDTO);
        });

        return statList;
    }

    @Override
    public List<ChargeStatistDTO> findHouseStatistPage(Token token, JSONObject jsonObject) throws Exception {
        JSONArray jsonArray = commonClient.getHousePage(jsonObject);
        if(Objects.nonEmpty(jsonArray)){
            List<ChargeStatistDTO>chargeStatistDTOList=new ArrayList<ChargeStatistDTO>();
            for(int i=0,len=jsonArray.size();i<len;i++){
                JSONObject json=jsonArray.getJSONObject(i);
                ChargeStatistDTO chargeStatistDTO=new ChargeStatistDTO();
                chargeStatistDTO.setCommunityName(json.getString("communityName"));
                chargeStatistDTO.setBuildName(json.getString("buildName"));
                chargeStatistDTO.setHouseName(json.getString("name"));
                chargeStatistDTO.setUnitName(json.getString("unitName"));
                chargeStatistDTO.setHouseNo(json.getString("id"));
                chargeStatistDTO.setCommunityNo(json.getString("communityNo"));
                chargeStatistDTO.setBuildNo(json.getString("buildNo"));
                chargeStatistDTO.setPayArea(json.getBigDecimal("payArea"));
                List<MeterManage>meterManageList=jdbcSession.findArray(MeterManage.class)
                        .eq("deleted", false)
                        .eq( "communityNo",chargeStatistDTO.getCommunityNo())
                        .eq("houseNo",chargeStatistDTO.getHouseNo())
                        .eq("status",true)
                        .exe();  //仪表
                List<ChargeHouseConfig> chargeHouseConfigList = jdbcSession.findArray(ChargeHouseConfig.class) //收费配置
                        .eq("deleted", false)
                        .eq("configStatus", true)
                        .eq( "communityNo",chargeStatistDTO.getCommunityNo())
                        .eq("buildNo",chargeStatistDTO.getBuildNo())
                        .eq("houseNo",chargeStatistDTO.getHouseNo())
                        .exe();
                if(chargeHouseConfigList.size()>0){
                    List<ChargeHouseSet>chargeHouseSetList=jdbcSession.findArray(ChargeHouseSet.class)
                            .eq("deleted",false)
                            .eq( "communityNo",chargeStatistDTO.getCommunityNo())
                            .eq("houseNo",chargeStatistDTO.getHouseNo())
                            .exe();
                    chargeStatistDTO.setConfigNumber(chargeHouseSetList.size());
                    chargeStatistDTO.setCreateTime(chargeHouseConfigList.get(0).getCreateTime());
                    chargeStatistDTO.setConfigStatus(chargeHouseConfigList.get(0).isConfigStatus());
                }
                if(meterManageList.size()>0){
                    chargeStatistDTO.setMeterNumber(meterManageList.size());
                }
                chargeStatistDTOList.add(chargeStatistDTO);
            }
            return chargeStatistDTOList;
        }else {
            return null;
        }
    }

    @Override
    public Object get(ChargeHouseConfig entity) {
        return Result.success(entity);
    }


    @Override
    public List<ChargeHouseSet> getChargeHouseSetBychargeHouseNo(JSONObject jsonObject) {
        String chargeHouseNo=jsonObject.getString("chargeHouseNo");
        List<ChargeHouseSet>chargeHouseSetList=jdbcSession.findArray(ChargeHouseSet.class)
                .eq("deleted",false)
                .eq( "chargeHouseNo",chargeHouseNo)
                .exe();
        chargeHouseSetList.forEach(item->{
            ChargeTypeConfig chargeTypeConfig=jdbcSession.findById(ChargeTypeConfig.class,item.getFeeTypeNo());
            MeterTypeConfig meterTypeConfig=jdbcSession.findById(MeterTypeConfig.class,chargeTypeConfig.getMeterTypeNo());
            item.setMeterTypeConfig(meterTypeConfig);
            ChargeProjectConfig chargeProjectConfig=jdbcSession.findById(ChargeProjectConfig.class,item.getProjectFeeNo());
            if(chargeProjectConfig!=null){
                item.setChargeProjectConfig(chargeProjectConfig);
                //阶梯价
                List<ChargeLadderConfig> configList = jdbcSession.findArray(ChargeLadderConfig.class)
                        .eq("chargeProjectNo",chargeProjectConfig.getId())
                        .order("usageStart","asc").exe();
                chargeProjectConfig.setLadderList(configList);
            }
        });
        return chargeHouseSetList;
    }

    @Override
    public List<MeterManage> getMeterManageByParam(JSONObject jsonObject) {
        String houseNo=jsonObject.getString("houseNo");
        String communityNo=jsonObject.getString("communityNo");
        List<MeterManage>meterManageList=jdbcSession.findArray(MeterManage.class)
                .eq("deleted", false)
                .eq( "communityNo",communityNo)
                .eq("houseNo",houseNo)
                .eq("status",true)
                .exe();  //仪表
        return meterManageList;
    }

    @ReqMapping("/saveHouseConfig")
    public Object saveHouseConfig(JSONObject jsonObject) throws Exception {
        DeptDTO deptDTO = deptService.getDept(jsonObject.getString("deptNo"));
        insetData(jsonObject,deptDTO);
        return Result.success();
    }

    @ReqMapping("/updateHouseConfig")
    public Object updateHouseConfig(JSONObject jsonObject) throws Exception {
        ChargeHouseConfig chargeHouseConfig = jdbcSession.findOne(ChargeHouseConfig.class)
                                        .eq("houseNo",jsonObject.getString("houseNo"))
                                        .exe();
        chargeHouseConfig.setOwnerNo(jsonObject.getString("ownerNo"));
        chargeHouseConfig.setChargeName(jsonObject.getString("ownerName"));
        return jdbcSession.updateById(chargeHouseConfig);
    }

    @ReqMapping("/deleteHouseConfig")
    public Object deleteHouseConfig(JSONObject jsonObject) throws Exception {
        ChargeHouseConfig chargeHouseConfig = jdbcSession.findOne(ChargeHouseConfig.class)
                                        .eq("houseNo",jsonObject.getString("houseNo"))
                                        .exe();
        chargeHouseConfig.setDeleted(true);
        return jdbcSession.updateById(chargeHouseConfig);
    }

}
